import { getErrorMessage } from './status'
import { IResponse } from './type'
import axios, { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import { API_BASE_URL } from '../constant'

// 请求超时中断
const TIMEOUT = 30000
// 跨域请求使用凭证
const CREDENTIALS = true
// 允许跨域
const ORIGIN = '*'
// token名称
const TOKEN_NAME = 'token'

// 创建axios实例
const instance: AxiosInstance = axios.create({
  baseURL: API_BASE_URL + '',
  timeout: TIMEOUT,
  //withCredentials: CREDENTIALS,
  headers: {
    'Content-Type': 'application/json;charset=UTF-8',
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Credentials': CREDENTIALS,
    'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
    'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, authorization',
    'Access-Control-Max-Age': 3600
  }
})

// 添加请求拦截器
instance.interceptors.request.use(
  (config: AxiosRequestConfig) => {
    // 在发送请求之前做些什么
    const token = sessionStorage.getItem(TOKEN_NAME)
    if (token) {
      config.headers!.Authorization = token
      config.headers!.token = token
      console.log(config.headers!.token)
    }
    return config
  },
  (error: AxiosError) => {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)

// 添加响应拦截器
instance.interceptors.response.use(
  (response: AxiosResponse<IResponse>) => {
    // 将响应数据中的token放入localStorage
    if (response.headers.authorization) {
      //sessionStorage.setItem(TOKEN_NAME, response.data.data)
      sessionStorage.setItem(TOKEN_NAME, response.headers.authorization)
    } else if (response.data && response.data.token != null) {
      //sessionStorage.setItem(TOKEN_NAME, response.data.data)
      sessionStorage.setItem(TOKEN_NAME, response.data.token)
    }
    // 响应正常则正常返回
    if (response.status === 200) {
      return response
    }
    // 响应数据中code不为0
    if (response.data.code !== 0) {
      alert(response.data.msg)
      return Promise.reject(response)
    }
    window.$message?.error(getErrorMessage(response.status))
    return Promise.reject(response)
  },
  (error: AxiosError) => {
    // 响应错误则抛出错误
    if (error.response) {
      window.$message?.error(getErrorMessage(error.response.status))
      return Promise.reject(error)
    }
    window.$message?.error('网络连接异常，请检查网络连接！')
  }
)

// 封装请求方法
const request = async (config: AxiosRequestConfig): Promise<IResponse> => {
  return new Promise((resolve, reject) => {
    instance
      .request<any, AxiosResponse<IResponse>>(config)
      .then((response: AxiosResponse<IResponse>) => {
        resolve(response.data)
      })
      .catch((error: AxiosError<IResponse | null | undefined>) => {
        console.log('捕获到请求异常: ', error.response)
        if (error.response?.data) {
          reject(error.response.data)
        } else if (error.response) {
          window.$notify?.error({
            title: '请求异常',
            meta:
              '请求中出现异常！\r\n状态码：' +
              error.response?.status +
              '\r\n内容：' +
              error.response?.statusText
          })
          reject(error.response?.data)
        } else {
          window.$notify?.error({
            title: '请求异常',
            meta: '网络连接异常，请检查网络连接！'
          })
        }
      })
  })
}

// 封装get请求
export function get<T>(config: AxiosRequestConfig): Promise<IResponse> {
  return request({ ...config, method: 'get' })
}

// 封装post请求
export function post<T>(config: AxiosRequestConfig): Promise<IResponse> {
  return request({ ...config, method: 'post' })
}

// 封装put请求
export function put<T>(config: AxiosRequestConfig): Promise<IResponse> {
  return request({ ...config, method: 'put' })
}

// 封装delete请求
export function del<T>(config: AxiosRequestConfig): Promise<IResponse> {
  return request({ ...config, method: 'delete' })
}

// 封装patch请求
export function patch<T>(config: AxiosRequestConfig): Promise<IResponse> {
  return request({ ...config, method: 'patch' })
}

// 封装下载请求
export function download<T>(config: AxiosRequestConfig): Promise<any> {
  return new Promise((resolve, reject) => {
    instance
      .request<any, AxiosResponse<IResponse>>({ ...config, method: 'get', responseType: 'blob' })
      .then((response: AxiosResponse<IResponse>) => {
        resolve(response.data)
      })
      .catch((error: AxiosError<IResponse | null | undefined>) => {
        reject(error.response)
      })
  })
}

export default instance
